/*
 * Package: org.grassfield.common.interceptor
 * FileName: AuthorizationInterceptor.java
 *  
 * Created by pandian on Jan 28, 2011
 */
package interceptor;

import java.util.Collection;
import java.util.Date;
import java.util.Map;

import bean.AuditLog;
import bean.User;
import service.IAuditLogService;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

/**
 * The Class AuthorizationInterceptor.
 */
public class AuthorizationInterceptor extends AbstractInterceptor {
	private static final long serialVersionUID = 1L;
	private IAuditLogService auditLogService;
	
	/**
	 * Sets the audit log service.
	 * 
	 * @param auditLogService the new audit log service
	 */
	public void setAuditLogService(IAuditLogService auditLogService) {
		this.auditLogService = auditLogService;
	}

	@Override
	public String intercept(ActionInvocation actionInvocation) throws Exception {
		AuditLog auditLog = new AuditLog();
		auditLog.setStatus("START");
		auditLog.setLogType(AuditLog.LOGIN);
		ActionContext invocationContext = actionInvocation.getInvocationContext();
		Map<String, Object> session = invocationContext.getSession();
		Object object = session.get("user$");
		auditLog.setUser((User) object);
		Object action = actionInvocation.getAction();
		if (object==null){
			String className = action.getClass().toString();
			auditLog.setMessage("Access request to "+className+". ");
			if (action instanceof ValidationAware){
				ValidationAware action2 = (ValidationAware) action;
				String signinClassStr = "action.HelloWorld";
				String signoutClassStr = "action.SignOutAction";
				if (!className.endsWith(signinClassStr) && !className.endsWith(signoutClassStr)) {
					action2.addActionError("Sorry! You must be authenticated to access this resource " + className);
					auditLog.setStatus("ERROR");
					auditLog.setMessage(auditLog.getMessage()+" User Authentication failed");
					auditLog.setLogTime(new Date());
					auditLogService.add(auditLog);
					return "login-error";
				}
			}
		}
		auditLog.setStatus("SUCCESS");
		String invoke=null;
		try {
			invoke = actionInvocation.invoke();
			action = actionInvocation.getAction();
			if (action instanceof ValidationAware){
				ValidationAware action2 = (ValidationAware) action;
				Collection<String> actionErrors = action2.getActionErrors();
				if (!actionErrors.isEmpty()){
					auditLog.setStatus("ERROR");
					for (String error:actionErrors){
						auditLog.setMessage(auditLog.getMessage()+". "+error);
					}
				}
			}
		} catch (Throwable e) {
			auditLog.setStatus("EXCEPTION");
			auditLog.setMessage(auditLog.getMessage()+". "+e.toString());
			e.printStackTrace();
		}
		
		auditLog.setLogTime(new Date());
		auditLogService.add(auditLog);
		return invoke;
	}
}
